home *** CD-ROM | disk | FTP | other *** search
- /* xsolar_irisgl.c
- * Displays a planet with a moon, orbiting a sun.
- * Uses X and IRIS GL widget.
- *
- * Exit with the ESCape key or through the window manager menu.
- */
- #include <Xm/Xm.h>
- #include <Xm/Frame.h>
- #include <Xm/Form.h>
- #include <X11/Xirisw/GlxMDraw.h>
- #include <X11/StringDefs.h>
- #include <X11/keysym.h>
-
- #include <gl/gl.h>
- #include <gl/device.h>
- #include <gl/get.h>
- #include <stdio.h>
- #include <math.h>
-
- typedef struct _spin {
- short year;
- } SPINDATA, *SPINPTR;
-
- /* function prototypes */
-
- void main(int argc, char **argv);
-
- void initCB (Widget w, XtPointer client_data, XtPointer call_data);
- void exposeCB (Widget w, XtPointer spin, XtPointer call_data);
- void resizeCB (Widget w, XtPointer spin, XtPointer call_data);
- void inputCB (Widget w, XtPointer client_data, XtPointer call_data);
-
- Boolean drawWP (XtPointer spin);
-
- void drawscene(SPINPTR spin);
- void setbeachball(int stripes);
- void beachball(unsigned long color1, unsigned long color2);
-
- SPINPTR spin;
-
- static XtAppContext app_context;
- static XtWorkProcId workprocid = NULL;
-
- /* Create application context, and a form widget to contain
- * the IRIS GL widget. Set up the IRIS GL widget callbacks
- */
- void main(int argc, char **argv)
- {
- Arg wargs[15];
- int n;
- Widget glw, toplevel, frame, form;
-
- static GLXconfig glxConfig [] = {
- {GLX_NORMAL, GLX_DOUBLE, TRUE},
- {GLX_NORMAL, GLX_RGB, TRUE},
- {GLX_NORMAL, GLX_ZSIZE, GLX_NOCONFIG},
- {0, 0, 0}
- };
-
- static String fallback_resources[] = {
- "*frame*shadowType: SHADOW_IN",
- "*glwidget*width: 750",
- "*glwidget*height: 600",
- NULL
- };
-
- /* create main data structure, spin pointer */
- spin = (SPINPTR) malloc (sizeof (SPINDATA));
- spin->year = 0;
-
- toplevel = XtAppInitialize(
- &app_context, /* Application context */
- "XSolar", /* Application class */
- NULL, 0, /* command line option list */
- &argc, argv, /* command line args */
- fallback_resources,
- NULL, /* argument list */
- 0); /* number of arguments */
-
- n = 0;
- form = XmCreateForm(toplevel, "form", wargs, n);
- XtManageChild(form);
-
- n = 0;
- XtSetArg(wargs[n], XtNx, 30); n++;
- XtSetArg(wargs[n], XtNy, 30); n++;
- XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
-
- XtSetArg(wargs[n], XmNleftOffset, 30); n++;
- XtSetArg(wargs[n], XmNbottomOffset, 30); n++;
- XtSetArg(wargs[n], XmNrightOffset, 30); n++;
- XtSetArg(wargs[n], XmNtopOffset, 30); n++;
- frame = XmCreateFrame (form, "frame", wargs, n);
- XtManageChild (frame);
-
- n = 0;
- XtSetArg(wargs[n], GlxNglxConfig, glxConfig); n++;
- glw = GlxCreateMDraw(frame, "glwidget", wargs, n);
- XtManageChild (glw);
- XtAddCallback(glw, GlxNginitCallback, initCB,
- (XtPointer) NULL);
- XtAddCallback(glw, GlxNexposeCallback, exposeCB,
- (XtPointer) spin);
- XtAddCallback(glw, GlxNresizeCallback, resizeCB,
- (XtPointer) spin);
- XtAddCallback(glw, GlxNinputCallback, inputCB,
- (XtPointer) NULL);
-
- workprocid = XtAppAddWorkProc (app_context, drawWP,
- (XtPointer) spin);
-
- XtRealizeWidget(toplevel); /* instantiate it now */
- XtAppMainLoop(app_context); /* loop for events */
- } /* end main() */
-
- /* initCB
- * The initCB subroutine initializes graphics modes and
- * transformation matrices.
- */
-
- void initCB (Widget w, XtPointer client_data, XtPointer call_data)
- {
- long gid1, xmax, ymax;
- float aspect;
-
- GLXwinset(XtDisplay(w), XtWindow(w));
-
- xmax = getgdesc(GD_XPMAX);
- ymax = getgdesc(GD_YPMAX);
- if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0)
- {
- fprintf(stderr,
- "This machine does not have a hardware zbuffer\n");
- exit(0);
- }
-
- zbuffer(TRUE);
- shademodel(FLAT);
-
- qdevice(LEFTMOUSE);
- qdevice(MIDDLEMOUSE);
- qdevice(ESCKEY);
- tie(LEFTMOUSE, MOUSEX, MOUSEY);
-
- /* separtae ModelView and Projection matrix stacks;
- * both are initialized with an identity matrix.
- */
- mmode(MVIEWING);
- aspect = (float) xmax / (float) ymax;
-
- /* projection commands replace projection matrix */
- perspective(450, aspect, 1.0, 25.0);
-
- /* viewing commands premultiply the ModelView matrix */
- polarview(12.0, 0, -100, 0);
- } /* end initCB() */
-
- /* exposeCB() and resizeCB() are called when the window
- * is uncovered, moved, or resized.
- */
-
- void exposeCB (Widget w, XtPointer ptr, XtPointer call_data)
- {
- SPINPTR spin;
-
- spin = (SPINPTR) ptr;
- GLXwinset (XtDisplay(w), XtWindow(w));
- drawscene(spin);
- }
-
- void resizeCB (Widget w, XtPointer ptr, XtPointer call_data)
- {
- GlxDrawCallbackStruct *call_ptr;
- SPINPTR spin;
-
- spin = (SPINPTR) ptr;
- call_ptr = (GlxDrawCallbackStruct *) call_data;
- GLXwinset (XtDisplay(w), XtWindow(w));
- viewport (0, (Screencoord) call_ptr->width-1,
- 0, (Screencoord) call_ptr->height-1);
- drawscene(spin);
- }
-
- /* inputCB() handles all types of input from the GL widget.
- * The KeyRelease handles the ESCape key, so that it exits
- * the program.
- */
- void inputCB (Widget w, XtPointer client_data,
- XtPointer call_data)
- {
- char buffer[1];
- KeySym keysym;
- GlxDrawCallbackStruct *call_ptr =
- (GlxDrawCallbackStruct *) call_data;
- XKeyEvent *kevent = (XKeyEvent *) (call_ptr->event);
-
- switch(call_ptr->event->type) {
- case KeyRelease:
- /* It is necessary to convert the keycode to a
- * keysym before checking if it is an escape */
- if (XLookupString(kevent,buffer,1,&keysym,NULL) == 1
- && keysym == (KeySym)XK_Escape)
- exit(0);
- break;
- default:
- break;
- }
- }
-
- /* drawWP() is called by the WorkProc. When the scene
- * is in automatic motion, the WorkProc calls this routine,
- * which adds 1 degree (10 tenths) to the cumulative amount
- * of rotation. drawscene() is called, so the image is
- * redrawn. It returns(FALSE) so the WorkProc does not
- * discontinue operation.
- */
- Boolean drawWP (XtPointer ptr)
- {
- SPINPTR spin;
-
- spin = (SPINPTR) ptr;
- spin->year = (spin->year + 10) % 3600;
- drawscene (spin);
- return (FALSE);
- }
-
-
- /* drawscene calculates angles relative to the spin->year
- * and then draws sun, planet, and moon.
- */
-
- void drawscene(SPINPTR spin)
- {
- static long blackcol[] = { 0, 0, 0 };
- static long bluecol[] = { 0, 0, 255 };
- static long whitecol[] = { 255, 255, 255 };
- short sunangle, dayangle, monthangle;
- /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
- float earthdist = 4.5, earthscale = 0.5;
- float moondist = 0.9, moonscale = 0.2;
-
- c3i(blackcol);
- /* clear color & z buffers */
- czclear(getgdesc(GD_ZMIN),getgdesc(GD_ZMAX));
- pushmatrix();
- sunangle = (spin->year*365/25) % 3600;
- /* sun rotates on axis every 25 days */
- rotate(sunangle, 'y');
- beachball(0x20C0FF, 0x200FFFF); /* colors in cpack format */
- popmatrix();
- pushmatrix();
- rotate(spin->year, 'y');
- translate(earthdist, 0.0, 0.0);
- pushmatrix();
- dayangle = (spin->year*50) % 3600; /* fudged */
- rotate(dayangle, 'y');
- scale(earthscale, earthscale, earthscale);
- c3i(bluecol);
- beachball(0xFF0000, 0xC02000); /* earth */
- popmatrix();
- monthangle = (spin->year*365/28) % 3600;
- rotate(monthangle, 'y');
- translate (moondist, 0.0, 0.0);
- scale(moonscale, moonscale, moonscale);
- c3i(whitecol);
- beachball(0xFFFFFF, 0xC0C0C0); /* moon */
- popmatrix();
-
- swapbuffers();
- } /* end drawscene() */
-
- /* BEACHBALL */
-
- /* three dimensional vector */
- typedef float vector[3];
-
- static vector front = { 0.0, 0.0, 1.0 };
- static vector back = { 0.0, 0.0, -1.0 };
- static vector top = { 0.0, 1.0, 0.0 };
- static vector bottom = { 0.0, -1.0, 0.0 };
- static vector right = { 1.0, 0.0, 0.0 };
- static vector left = { -1.0, 0.0, 0.0 };
- static vector center = { 0.0, 0.0, 0.0 };
-
- /* Number of colored stripes. Should be even to look right */
- #define BEACHBALL_STRIPES 12
-
- /* Default number of polygons making up a stripe. Should be even */
- #define BEACHBALL_POLYS 16
-
- /* array of vertices making up a stripe */
- static vector stripe_point[BEACHBALL_POLYS + 3];
-
- /* has the beachball been initialized */
- static Boolean beachball_initialized = FALSE;
-
- /* Number of polygons making up a stripe */
- static int beachball_stripes;
-
- /* Number of vertices making up a stripe */
- static int stripe_vertices;
-
- /* Initialize beachball_point array to be a stripe
- * of unit radius.
- */
- void setbeachball(int stripes)
- {
- int i,j;
- float x,y,z; /* vertex points */
- float theta,delta_theta; /* angle from top pole to bottom pole */
- float offset; /* offset from center of stripe to vertex */
- float cross_radius; /* radius of cross section at current latitude */
- float cross_theta; /* angle occupied by a stripe */
-
- beachball_stripes = stripes;
-
- /* polys distributed by even angles from top to bottom */
- delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
- theta = delta_theta;
-
- cross_theta = 2.0*M_PI/(float)beachball_stripes;
-
- j = 0;
-
- stripe_point[j][0] = top[0];
- stripe_point[j][1] = top[1];
- stripe_point[j][2] = top[2];
- j++;
-
- for (i = 0; i < BEACHBALL_POLYS; i += 2) {
- cross_radius = fsin(theta);
- offset = cross_radius * ftan(cross_theta/2.0);
-
- stripe_point[j][0] = - offset;
- stripe_point[j][1] = fcos(theta);
- stripe_point[j][2] = cross_radius;
- j++;
-
- stripe_point[j][0] = offset;
- stripe_point[j][1] = stripe_point[j-1][1];
- stripe_point[j][2] = stripe_point[j-1][2];
- j++;
-
- theta += delta_theta;
- }
-
- stripe_point[j][0] = bottom[0];
- stripe_point[j][1] = bottom[1];
- stripe_point[j][2] = bottom[2];
-
- stripe_vertices = j + 1;
-
- beachball_initialized = TRUE;
- }
-
- /*
- * Draws a canonical beachball. The colors are cpack values
- * when in RGBmode, colormap indices when in colormap mode.
- */
- void beachball(unsigned long c1, unsigned long c2)
- {
- long mode;
- float angle, delta_angle;
- int i,j;
-
- if (! beachball_initialized)
- setbeachball(BEACHBALL_STRIPES);
-
- mode = getdisplaymode();
-
- angle = 0.0;
- delta_angle = 360.0/(float)beachball_stripes;
-
- for (i = 0; i < beachball_stripes; i++) {
- switch(mode) {
- case DMSINGLE: case DMDOUBLE:
- if ( i%2 == 0)
- color(c1);
- else color(c2);
- break;
- case DMRGB: case DMRGBDOUBLE:
- if ( i%2 == 0)
- cpack(c1);
- else cpack(c2);
- break;
- }
-
- pushmatrix();
- rot(angle, 'y');
- angle += delta_angle;
-
- bgntmesh();
- for (j = 0; j < stripe_vertices; j++)
- v3f(stripe_point[j]);
- endtmesh();
- popmatrix();
- }
- }
-
-